<?php
/**
 * +--------------------------------------------------------+
 * @Created by Phpstorm.
 * @Category RoleController.php
 * @Depiction
 * @Author hwy <429208948@qq.com>
 * @Date 2022/3/25  16:46
 * +--------------------------------------------------------+
 */

namespace App\Http\Controllers\Admin\V1;

use App\Services\AdminService;
use App\Services\RoleService;
use App\Services\UserService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Spatie\Permission\Guard;

class RoleController extends Controller
{
    protected $roleService;
    protected $adminService;

    public function __construct(RoleService $roleService, AdminService $adminService)
    {
        $this->roleService  = $roleService;
        $this->adminService = $adminService;
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws \App\Exceptions\ValidationException
     * @Depiction
     * @Author hwy <429208948@qq.com>
     * @Date 2022/4/7  13:48
     */
    public function index(Request $request)
    {
        $rules = [
            'page'       => ['nullable', 'numeric', 'gte:0'],
            'limit'      => ['nullable', 'numeric', 'gte:1', 'lte:100'],
            'sort'       => ['nullable',],
            'order'      => ['nullable', 'string'],
            'name'       => ['nullable', 'string', 'between:1,60',],
            'guard_name' => ['required', 'string', Rule::in(['api', 'admin']),],
            'start_at'   => ['required_with:end_at', 'date_format:Y-m-d H:i:s', 'before_or_equal:end_at'],
            'end_at'     => ['required_with:start_at', 'date_format:Y-m-d H:i:s', 'after_or_equal:start_at'],
        ];

        $attributes = [
            'page'       => '页数',
            'limit'      => '每页条数',
            'sort'       => '排序字段',
            'order'      => '排序顺序',
            'name'       => '角色标识',
            'guard_name' => '对应规则',
        ];

        $messages = [];

        $validated = $this->validate($request, $rules, $messages, $attributes);

        $data = $this->roleService->getList($validated);

        return $this->responseSuccessData('请求成功！', $data);

    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @Depiction
     * @Author hwy <429208948@qq.com>
     * @Date 2022/4/7  14:25
     */
    public function show(Request $request)
    {
        $id = $request->get('id', 0);

        $data = $this->roleService->getInfoWithPermission($id);

        return $this->responseSuccessData('请求成功！', $data);
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws \App\Exceptions\ValidationException
     * @Depiction 获取全部角色
     * @Author hwy <429208948@qq.com>
     * @Date 2022/4/7  14:32
     */
    public function allIndex(Request $request): JsonResponse
    {
        $rules      = [
            'guard_name' => ['required', 'string', Rule::in(['api', 'admin']),],
        ];
        $attributes = [
            'guard_name' => '对应规则',
        ];
        $messages   = [];
        $validated  = $this->validate($request, $rules, $messages, $attributes);

        $data = $this->roleService->getAllList($validated);

        return $this->responseSuccessData('请求成功！', $data);

    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws \App\Exceptions\ValidationException
     * @Depiction
     * @Author hwy <429208948@qq.com>
     * @Date 2022/4/7  16:17
     */
    public function create(Request $request)
    {
        $tableNames = config('permission.table_names');
        $rules      = [
            'name'       => ['required', 'string', 'between:2,60', 'unique:' . $tableNames['roles'],],
            'guard_name' => ['required', 'string', 'between:2,60', Rule::in(['api', 'admin']),],
        ];
        $attributes = [
            'name'       => '角色标识',
            'guard_name' => '对应规则',
        ];
        $messages   = [];
        $validated  = $this->validate($request, $rules, $messages, $attributes);

        $validated['guard_name'] = $validated['guard_name'] ?? Guard::getDefaultName(static::class);

        if ($this->roleService->getInfoByName($validated)) {
            return $this->responseErrorData("A role `{$validated['name']}` already exists for guard `{$validated['guard_name']}`.");
        }

        $this->roleService->create($validated);

        return $this->responseSuccessData('创建成功！');
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws \App\Exceptions\ValidationException
     * @Depiction 授权权限
     * @Author hwy <429208948@qq.com>
     * @Date 2022/4/7  16:18
     */
    public function update(Request $request)
    {
        $role = $this->roleService->getInfo($request->post('id', 0));
        if (empty($role)) {
            return $this->responseErrorData('用户不存在！');
        }

        $tableNames = config('permission.table_names');
        $rules      = [
            'id'         => ['required', 'integer',],
            'name'       => ['required', 'string', 'between:2,60', Rule::unique($tableNames['roles'])->ignore($role),],
            'guard_name' => ['required', 'string', 'between:2,60', Rule::in(['api', 'admin']),],
        ];
        $attributes = [
            'id'         => 'ID',
            'name'       => '角色标识',
            'guard_name' => '对应规则',
        ];
        $messages   = [];
        $validated  = $this->validate($request, $rules, $messages, $attributes);

        $result = $this->roleService->update($role, $validated);

        if ($result) {
            return $this->responseSuccessData('修改成功！');
        } else {
            return $this->responseErrorData('修改失败！');
        }

    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @Depiction
     * @Author hwy <429208948@qq.com>
     * @Date 2022/4/7  16:23
     */
    public function delete(Request $request)
    {
        $id   = $request->post('id', 0);
        $role = $this->roleService->getInfo($id);
        if (empty($role)) {
            return $this->responseErrorData('用户不存在！');
        }

        $result = $this->roleService->delete($role);

        if ($result) {
            return $this->responseSuccessData('删除成功！');
        } else {
            return $this->responseErrorData('删除失败！');
        }
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws \App\Exceptions\ValidationException
     * @Depiction 授权权限
     * @Author hwy <429208948@qq.com>
     * @Date 2022/4/7  17:40
     */
    public function syncPermissions(Request $request)
    {
        $tableNames = config('permission.table_names');
        $rules      = [
            'id'          => ['required', 'integer'],
            'permissions' => ['array'],
        ];
        $attributes = [
            'id'          => '角色ID',
            'permissions' => '权限/目录',
        ];
        $messages   = [];
        $validated  = $this->validate($request, $rules, $messages, $attributes);

        $id = $request->post('id', 0);

        $this->roleService->syncPermissions($id, $validated);

        return $this->responseSuccessData('修改成功！');
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws \App\Exceptions\ValidationException
     * @Depiction
     * @Author hwy <429208948@qq.com>
     * @Date 2022/4/17  15:29
     */
    public function syncRoles(Request $request)
    {
        $guardName = $request->post('guard_name', '');
        switch ($guardName) {
            case 'api':
                $guardName = 'App\Models\User';
                break;
            case 'admin':
                $guardName = 'App\Models\Admin';
                break;
            default:
                $guardName = '';
        }

        $rules      = [
            'guard_name' => ['required', 'string', 'between:2,60', Rule::in(['api', 'admin']),],
            'guard_id'   => ['required', 'integer', 'exists:' . $guardName . ',id'],
            'roles'      => ['array'],
        ];
        $attributes = [
            'guard_name' => '对应规则',
            'guard_id'   => '对应规则id',
            'roles'      => '角色',
        ];
        $messages   = [];
        $validated  = $this->validate($request, $rules, $messages, $attributes);

        $guard_id = $request->post('guard_id', 0);
        $guard    = $this->adminService->getValue($guard_id);

        $roles = isset($validated['roles']) ?
            $this->roleService->getInfo($validated['roles']) :
            [];

        $guard->syncRoles($roles);

        return $this->responseSuccessData('修改成功！');
    }

}
